﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Commands;
using Prism.Events;
using System.Windows.Input;
using HandyControl.Controls;
using Prism.Mvvm;
using SoonCode.Core;
using SoonCode.FocusTest.Events;
using SoonCode.FocusTest.Models;
using SoonCode.FocusTest.Utils;
using System.Windows;
using Prism.Services.Dialogs;

namespace SoonCode.FocusTest.ViewModels
{
    internal class TestItemCViewModel : BindableBase
    {
        private int TestItemIndex = 3;
        private RandomHelper randomHelper ;
        private int tabIndex = 0;
        private int err = 0;
        private TestInfo testInfo;
        private IEventAggregator aggregator;
        private int level = 1;
        private bool stop = false;
        private string[] imgData5 = ["yuanxing", "sanjiao", "zhengfang", "jiahao", "jianhao", "dengyu"];
        private string[] imgData2 = ["xiaozhu", "xiaoyu", "banma", "shizi", "zhangyu", "pangxie","wugui"];
        private string[] testImageData = [];
        private SubscriptionToken answerToken;
        private SubscriptionToken changeTestToken;
        private List<ObservableCollection<ItemHelper>> questionList;
        private IDialogService dialogService;
        private HashSet<int> stopPlay=new HashSet<int>();
        private string helpSoundText = "停止播放提示语";
        private bool helpIsPlay = true;
        private int errCount = 0;
        private Visibility fiveAgeTip=Visibility.Visible;
        private Visibility twoAgeTip=Visibility.Collapsed;
        
        public Visibility TwoAgeTip
        {
            get { return twoAgeTip; }
            set
            {
                twoAgeTip = value;
                RaisePropertyChanged();
            }
        }
        public Visibility FiveAgeTip
        {
            get { return fiveAgeTip; }
            set
            {
                fiveAgeTip = value;
                RaisePropertyChanged();
            }
        }
        public string HelpSoundText
        {
            get { return helpSoundText; }
            set
            {
                helpSoundText = value;
                RaisePropertyChanged();
            }
        }

        public int Level
        {
            get { return level; }
            set
            {
                level = value;
                RaisePropertyChanged();
            }
        }
        private ObservableCollection<ItemHelper> itemList;
        public ObservableCollection<ItemHelper> ItemList
        {
            get { return itemList; }
            set
            {
                itemList = value;
                RaisePropertyChanged();
            }
        }

        public TestItemCViewModel(IEventAggregator aggregator,IDialogService dialogService)
        {
            
            this.aggregator = aggregator;
            this.dialogService= dialogService;
            aggregator.GetEvent<EndTestEvent>().Subscribe(() =>
            {
                aggregator.GetEvent<StudentAnswerEvent>().Unsubscribe(answerToken);
                stop = true;
                stopPlay.Add(Level);
            });
            aggregator.GetEvent<TestLoadEvent>().Subscribe(OnLoaded);

        }
        private void playSound()
        {
            if (GlobalModel.Instance.MemberInfo.age >= 5)
            {
                SoundPlayer.Play("1000:item3.mp3");
                FiveAgeTip = Visibility.Visible;
                TwoAgeTip = Visibility.Collapsed;
            }
            else
            {
                SoundPlayer.Play("1000:item3-2.mp3");
                TwoAgeTip = Visibility.Visible;
                FiveAgeTip = Visibility.Collapsed;
            }
        }
        private void OnLoaded(int p)
        {
            if (p != this.TestItemIndex - 1)
            {
                if (answerToken != null)
                    aggregator.GetEvent<StudentAnswerEvent>().Unsubscribe(answerToken);
                if(changeTestToken!=null)
                    aggregator.GetEvent<ChangeTestEvent>().Unsubscribe(changeTestToken);
                stop = true;
                stopPlay.Add(Level);
                return;
            }
            int age=GlobalModel.Instance.MemberInfo.age;
            randomHelper = new RandomHelper(1, age>=5?7:8);
            testImageData=age>=5?imgData5:imgData2;
            playSound();
            this.testInfo = GlobalModel.Instance.TestInfo;
            TabIndex = 0;
            Task.Run(GenerateList);
            Level = 1;
            changeTestToken = aggregator.GetEvent<ChangeTestEvent>().Subscribe((p) =>
            {
                if (p != this.TestItemIndex - 1)
                {
                    stopPlay.Add(Level);
                }
            });
            aggregator.GetEvent<EndTestEvent>().Subscribe(() =>
            {
                stopPlay.Add(Level);
            });
            answerToken = aggregator.GetEvent<StudentAnswerEvent>().Subscribe(SutdentAnswer);
            stop = false;
        }
        private void SutdentAnswer(EventInfo payload)
        {
            if (payload == null || payload.Type != "itemC")
            {
                return;
            }
            int index = Convert.ToInt16(payload.Data["index"]);
            bool answer = payload.Data["img"].ToString() == ItemList[index].imgName;
            ItemList[index].color = answer ? "Green" : "Red";
            if (!answer)
            {
                errCount++;
                stop = true;
            }

            foreach (ItemHelper helper in ItemList)
            {
                if (helper.color == null)
                    return;
            }

            if (stop)
            {
                complete();
                return;
            }
            Level++;
            Test();
        }
        public int TabIndex
        {
            get { return tabIndex; }
            set
            {
                tabIndex = value;
                RaisePropertyChanged();
            }
        }
        public ICommand HelpCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    if (helpIsPlay)
                    {
                        SoundPlayer.Stop();
                        HelpSoundText = "播放提示语";
                        helpIsPlay = false;
                    }
                    else
                    {
                        playSound();
                        HelpSoundText = "停止播放提示语";
                        helpIsPlay = true;
                    }
                });
            }
        }
        public ICommand SkipCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    SoundPlayer.Stop();
                    this.aggregator.GetEvent<ChangeTestEvent>().Publish(TestItemIndex);
                });
            }
        }
        public ICommand StartCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    TabIndex = 1;
                    stopPlay.Clear();
                    Test();
                });
            }
        }

        public ICommand AnswerErrorCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    stop = true;
                    stopPlay.Add(Level);
                    complete();
                });
            }
        }
        public ICommand AnswerRightCommand
        {
            get
            {
                return new DelegateCommand(() =>
                {
                    SoundPlayer.Stop();
                    stop = true;
                    stopPlay.Add((Level));
                    Level++;
                    Test();
                });
            }
        }

        private void complete()
        {
            string errNum = "0";
            if (Level<=11)
            {
                errNum=DialogUtil.Prompt(dialogService, "请输入不通过关的错误图形个数", (p) =>
                {
                    int r;
                    if (int.TryParse(p, out r))
                    {
                        if (r > 0 && r <= 30) return true;
                        return false;
                    }
                    else
                    {
                        return false;
                    }
                },errCount.ToString());
            }
            DialogUtil.Show(aggregator, $"通过关数=（{Level - 1}）关，本项结束，进入下一项");
            testInfo.data[TestItemIndex - 1].item_score = (int)((double)((Level>11?11:Level)*30 - errNum.ToInt()) / (11*30) * 100) + "";
            this.aggregator.GetEvent<ChangeTestEvent>().Publish(TestItemIndex);
        }

        private void GenerateList()
        {
            questionList = new List<ObservableCollection<ItemHelper>>();
            for (int i = 0; i < 11; i++)        
            {
                string numbers = randomHelper.next(30);
                ObservableCollection<ItemHelper> items = new ObservableCollection<ItemHelper>();
                foreach (var s in numbers)
                {
                    ItemHelper helper = new ItemHelper();
                    int index = s.ToString().ToInt() - 1;
                    helper.img = $"pack://application:,,,/Images/{testImageData[index]}.png";
                    helper.imgName = testImageData[index];
                    helper.sound = testImageData[index] + ".wma";
                    items.Add(helper);
                }
                questionList.Add(items);
            }
            ItemList = questionList[0];
        }
        private async void Test()
        {
            errCount = 0;
            if (Level > 11)
            {
                complete();
                return;
            }
            EventInfo info = new EventInfo() { Type = "itemC" };
            int theLevel = Level;
            info.Data["Level"]=theLevel;
            this.aggregator.GetEvent<LevelUpdateEvent>().Publish(info);
            ItemList = questionList[Level - 1];
            SoundPlayer.PlayStrings(["Countdown:3000", "3:1000", "2:1000", "1:1000"], () => { });
            await Task.Delay(6500);
            try
            {
                double speed = 0.7 + theLevel / 9.0;
                for (var index = 0; index < ItemList.Count; index++)
                {   
                    if (stopPlay.Contains(theLevel)) return;
                    ItemHelper itemHelper = ItemList[index];
                    info.Data["index"] = index;
                    info.Data["Level"] = theLevel;
                    this.aggregator.GetEvent<QuestionChangeEvent>().Publish(info);
                    SoundPlayer.Play(itemHelper.sound, speed);
                    await Task.Delay(2350 - theLevel * 145);
                }
            }
            catch (Exception e)
            {
            }
        }
    }

    public class ItemHelper : BindableBase
    {
        private string _color;
        public string color
        {
            get { return _color; }
            set
            {
                _color = value;
                RaisePropertyChanged();
            }
        }
        public string img { get; set; }
        public string imgName { get; set; }
        public string sound { get; set; }
    }
}
